home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
source
/
zendisk2
/
lst11-29.asm
< prev
next >
Wrap
Assembly Source File
|
1990-02-15
|
5KB
|
152 lines
;
; *** Listing 11-29 ***
;
; Searches a text buffer for a sequence of bytes by using
; REPNZ SCASB to identify bytes in the buffer that
; potentially could start the sequence and then checking
; only starting at those qualified bytes for a match with
; the sequence by way of REPZ CMPS.
;
jmp Skip
;
; Text buffer that we'll search.
;
TextBuffer label byte
db 'This is a sample text buffer, suitable '
db 'for a searching text of any sort... '
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 '
db 'End of text... '
TEXT_BUFFER_LENGTH equ ($-TextBuffer)
;
; Sequence of bytes that we'll search for.
;
SearchSequence label byte
db 'text...'
SEARCH_SEQUENCE_LENGTH equ ($-SearchSequence)
;
; Searches a buffer for the first occurrence of a specified
; sequence of bytes.
;
; Input:
; CX = length of sequence of bytes to search for
; DX = length of buffer to search in
; DS:SI = start of sequence of bytes to search for
; ES:DI = start of buffer to search
;
; Output:
; ES:DI = pointer to start of first occurrence of
; desired sequence of bytes in the buffer, or
; 0:0 if the sequence wasn't found
;
; Registers altered: AL, BX, CX, DX, SI, DI, BP
;
; Direction flag cleared
;
; Note: Does not handle search sequences or text buffers
; that are longer than 64K bytes or cross segment
; boundaries.
;
; Note: Assumes non-zero length of search sequence (CX > 0),
; and search sequence shorter than 64K (CX <= 0ffffh).
;
; Note: Assumes buffer is longer than search sequence
; (DX > CX). Zero length of buffer (DX = 0) is taken
; to mean that the buffer is 64K bytes long.
;
FindSequence:
cld
lodsb ;get the first byte of the search
; sequence, which we'll leave in AL
; for faster searching
mov bp,si ;set aside the sequence start
; offset plus one
dec cx ;we don't need to compare the first
; byte of the sequence with CMPS,
; since we'll do it with SCAS
mov bx,cx ;set aside the sequence length
; minus 1
sub dx,cx ;difference between buffer and
; search sequence lengths plus 1
; (# of possible sequence start
; bytes to check in the buffer)
mov cx,dx ;put buffer search length in CX
jnz FindSequenceLoop ;start normally if the
; buffer isn't 64Kb long
dec cx ;the buffer is 64K bytes long-we
; have to check the first byte
; specially since CX = 0 means
; "do nothing" to REPNZ SCASB
scasb ;check the first byte of the buffer
jz FindSequenceCheck ;it's a match for 1 byte,
; at least-check the rest
FindSequenceLoop:
repnz scasb ;search for the first byte of the
; search sequence
jnz FindSequenceNotFound
;it's not found, so there are no
; possible matches
FindSequenceCheck:
;we've got a potential (first byte)
; match-check the rest of this
; candidate sequence
push di ;remember the address of the next
; byte to check in case it's needed
mov dx,cx ;set aside the remaining length to
; search in the buffer
mov si,bp ;point to the rest of the search
; sequence
mov cx,bx ;sequence length (minus first byte)
shr cx,1 ;convert to word for faster search
jnc FindSequenceWord ;do word search if no odd
; byte
cmpsb ;compare the odd byte
jnz FindSequenceNoMatch
;odd byte doesn't match,
; so we haven't found the
; search sequence here
FindSequenceWord:
jcxz FindSequenceFound
;since we're guaranteed to have
; a non-zero length, the
; sequence must be 1 byte long
; and we've already found that
; it matched
repz cmpsw ;check the rest of the sequence a
; word at a time for speed
jz FindSequenceFound ;it's a match
FindSequenceNoMatch:
pop di ;get back the pointer to the next
; byte to check
mov cx,dx ;get back the remaining length to
; search in the buffer
and cx,cx ;see if there's anything left to
; check
jnz FindSequenceLoop ;yes-check next byte
FindSequenceNotFound:
sub di,di ;return 0 pointer indicating that
mov es,di ; the sequence was not found
ret
FindSequenceFound:
pop di ;point to the buffer location at
dec di ; which the first occurrence of the
; sequence was found (remember that
; earlier we pushed the address of
; the byte after the potential
; sequence start)
ret
;
Skip:
call ZTimerOn
mov si,offset SearchSequence
;point to search sequence
mov cx,SEARCH_SEQUENCE_LENGTH
;length of search sequence
mov di,seg TextBuffer
mov es,di
mov di,offset TextBuffer
;point to buffer to search
mov dx,TEXT_BUFFER_LENGTH
;length of buffer to search
call FindSequence ;search for the sequence
call ZTimerOff